<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  
  <script>
    /* 
    Promise:ES6新出的一个对象,用于管理异步任务,解决回调地狱
    怎么解决:用的是Promise的链式调用的特征
    1.基础用法:
      创建Promise对象
      let p = new Promise((resolve,reject)=>{
        setTimeout(()=>{
          resolve('成功')
          reject('失败')
        },2000)//2秒好比是ajax小请求+响应总耗费时间(模拟)
      })
      如何拿到Promise对象里成功或者失败的结果
      resolve()->.then()里面函数体代码执行
      reject()->.catch()里函数体代码执行
      p.then(res=>{
        console.log(res)
      })
      p.catch(err=>{
        console.log(err)
      })

      高级用法1:
      口诀:Promise对象.then() 在原地会有一个返回值,是一个全新的Promise对象
      let pB = p.then()
      console.log(pB===p)   false

      高级用法2:
      口诀:Promise对象.catch() 在原地忽悠一个返回值,是一个全新的Promise对象
      链式调用:每个函数里返回同样的一个对象,继续 . 调用内部的其他方法,一直 . 下去就是链式调用
      let pB = p.then().catch()
      console.log(pB===p)

      高级用法3:
      口诀:then()里函数体里的return,返回给下一个Promise对象使用
      情况1:return的是非Promise对象
      let pB = p.then(res=>{   //res:'成功'
        return 1000         //特殊:return给pB(下一个Promise对象的then里使用)
      })

      pB.then(result=>{
        console.log(result)  //1000
      })

      情况2:return的是一个新的Promise对象,替换then()函数默认在原地返回的那个全新的Promise对象
      下一个then里拿到的是return的这个Promise对象里resolve的结果
      let pB = p.then(res => { // res : '成功'
          console.log(res);
          return new Promise((resolve, reject) => {
              setTimeout(() => {
                  resolve('第二次成功值')
              }, 3000)
          })
      })

      pB.then(result => {
          console.log(result); // 第二次成功值
      })

      高级用法4:catch()里return会返回到,下一个Promise对象的then里使用
      总结:无论then/catch 括号里函数体的return,都会返回给下一个Promise的'then'里
      let pB = p.catch(err=>{
        console.log(err);
        return 1000;
      })

      pB.then(result=>{
        console.log(result); //1000
      })

      awaitTo技术:
      为什么:因为await 只能默认取代then函数,只能拿到then的结果
      如果await后面Promise内报错,我们需要使用try+catch来进行捕获
      解决:我门想把try+catch优化掉,让await可以提取到成功和失败的结果
    */
    let p = new Promise((resolve,reject)=>{
      //异步任务.定时器/ajax请求
      setTimeout(()=>{
        resolve('成功')  //会进入.then
        // reject('失败') // 会进入.catch
      },2000)
    })
    //then()里函数体的return 返回给下一个Promise对象使用
    //1.return 的是一个非Promise对象
    let p2=p.then(result=>{
      return 1000 //return 给下一个Promise对象的then里使用
    })
    // p2.then(result=>{
    //   console.log(result);
    // })


    //例如:
      function myAxios(){
        let pA = new Promise((resolve,reject)=>{
          setTimeout(()=>{
            reject('失败')
          },2000)
        })
        return pA
      }
      let pB =myAxios().then(result=>{ //模拟axios()函数,以前await pA拿结果,用await 取pB结果(只能拿成功的)
        return [null,result]
      }).catch(err=>{
        return[err,null] //会返回给pB的then使用(pA的错误信息传递下去)
      })
      
      async function myFn(){ //逻辑页面拿处理后的Promise对象里结果(有成功/失败)
        const [err,res] = await pB  //await还是取代pB的then
        if(err) console.error(err);
        else console.log(res);
        //1个变量位置无法区别是成功值/失败值,那么我们在中转地传出一个数组,
        //数组中的第一个位置错误信息,第二个是正确新信息
      }
      myFn()
  </script>
</body>
</html>